﻿using System;
using System.Threading;
using System.Linq;
using System.Messaging;

namespace Aden.Util.queue
{
    public class MSMQ
    {
        private static ManualResetEvent ManualReset = new ManualResetEvent(false);
        private string path = ".\\Private$\\ADENQueue";


        private MessageQueue Createqueue(string queuePath)
        {
            try
            {
                lock (path)
                {
                    if (MessageQueue.Exists(queuePath))
                    {
                        //throw new Exception("Exist message queue");
                        //获取这个消息队列
                        return new MessageQueue(queuePath);
                    }

                    //不存在，就创建一个新的，并获取这个消息队列对象
                    return MessageQueue.Create(queuePath);
                    //     path = queuePath;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        #region 发送消息到队列
        public void SendMessage(string guid, string qStr)
        {
            try
            {   //连接到本地队列
                using (MessageQueue myQueue = Createqueue(path))
                {
                    using (Message myMessage = new Message())
                    {
                        myMessage.Body = qStr;
                        myMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                        myMessage.Label = guid;
                        //myMessage.CorrelationId = myMessage.Id + "//" + guid;
                        //发生消息到队列中
                        myQueue.Send(myMessage);

                        ManualReset.Set();
                    }

                    string threadId = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
                    //Console.WriteLine($"消息发送成功: {qStr};当前线程id:{threadId}");
                }
            }
            catch (MessageQueueException e)
            {
                throw e;
            }
        }
        #endregion

        #region 连接消息队列读取消息
        public string ReceiveMessage(string guid)
        {
            try
            {
                using (MessageQueue myQueue = Createqueue(path))
                {
                    myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                    string msgId = "";
                    long now = DateTime.Now.Ticks;
                    while ((DateTime.Now.Ticks - now) < 2 * 60 * 10000000)
                    {
                        try
                        {
                            Message msg = myQueue.GetAllMessages().FirstOrDefault(q => q.Label == guid);
                            if (msg == null) throw new Exception("");

                            msgId = msg.Id;

                            //从队列中接收消息
                            return myQueue.ReceiveById(msgId).Body.ToString();
                        }
                        catch { }
                        ManualReset.WaitOne(1000);
                        ManualReset.Reset();
                    }
                }
                throw new Exception("Can't get message");
            }
            catch (InvalidCastException e)
            {
                throw e;
            }

        }
        #endregion
    }
}
